﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace Cataloger
{
    /// <summary>
    /// Klasa opisująca Folder (strukturę danych gromadzącą
    /// Pliki i Foldery (podfoldery)). Dziedziczy ona po klasie
    /// abstrakcyjne ObiektDyskowy
    /// </summary>
    [Serializable]
    public class Folder : ObiektDyskowy,IFoldery
    {
		#region Fields (1) 

        /// <summary>
        /// Przechowuje obiekty dyskowe znajdujace sie w tym folderze
        /// </summary>
        HashSet<ObiektDyskowy> obiektyDyskowe = new HashSet<ObiektDyskowy>();

		#endregion Fields 

		#region Constructors (1) 

        public Folder(DirectoryInfo directory)
        {
            this.nazwa = directory.Name;
            this.atrybuty = directory.Attributes;
            this.dataDost = directory.LastAccessTime;
            this.dataUtw = directory.CreationTime;
            this.dataMod = directory.LastWriteTime;
        }

		#endregion Constructors 

		#region Properties (16) 

         public override bool CzyIstniejeSciezka
        {
            get
            {
                if (this.Nosnik.CzyPodlaczony())
                {
                    if (Directory.Exists(this.SciezkaRzeczyiwsta))
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
        }

        public override Kategoria Kategoria
        {

            set
            {
                foreach (ObiektDyskowy item in ObiektyDyskowe)
                {
                    item.Kategoria = value;
                }
            }
        }

        /// <summary>
        /// Podaje liczbę plików w folderze z najwyższego poziomu
        /// </summary>
        /// <value>Liczbe plików w folderze</value>
        public long LiczbaPlikow
        {
            get { return Pliki.Count; }
        }

        /// <summary>
        /// Podaje liczbę podfolderów w folderze z najwyższego poziomu
        /// </summary>
        /// <value>Liczbe podfolderow w folderze</value>
        public long LiczbaPodfolderow
        {
            get { return Podflodery.Count; }
        }

        public override Nosnik Nosnik
        {
            get
            {
                return GetNosnik(this);

            }
        }

        public HashSet<ObiektDyskowy> ObiektyDyskowe
        {
            get { return obiektyDyskowe; }
            set { obiektyDyskowe = value; }
        }

        override public string OpisStatusStrip
        {
            get
            {
                return string.Format("{0} ({1}), Data: {3}, Rozmiar: {2} (Plików: {4} Podfolderów: {5})",
                    this.Nazwa, "Folder", this.Rozmiar.ToProperUnit(), this.DataUtw.ToShortDateString(),
                    this.LiczbaPlikow.ToString("N0"), this.LiczbaPodfolderow.ToString("N0"));
            }
        }

        public override string OpisToolTip
        {
            get
            {
                StringBuilder st = new StringBuilder();
                st.AppendLine(this.Nazwa);
                st.AppendLine(this.Rozmiar.ToProperUnit());
                st.AppendLine(string.Format("Pliki: {0} Podfoldery:{1}", this.LiczbaPlikow.ToString("N0"), this.LiczbaPodfolderow.ToString("N0")));
                return st.ToString();
            }
        }

        public override string OpisWlasciwosci
        {
            get
            {
                StringBuilder st = new StringBuilder();
                st.AppendLine("Nazwa: \t\t" + this.Nazwa);
                st.AppendLine("Sciezka: \t" + this.Sciezka);
                st.AppendLine("Rozmiar: \t" + this.Rozmiar.ToProperUnit());
                st.AppendLine("Data utw: \t" + this.dataUtw.ToShortDateString() + "  " + this.dataUtw.ToShortTimeString());
                st.AppendLine("Data mod: \t" + this.dataMod.ToShortDateString() + "  " + this.dataMod.ToShortTimeString());
                st.AppendLine("Data dos: \t" + this.dataDost.ToShortDateString() + "  " + this.dataDost.ToShortTimeString());
                st.AppendLine("Atrybuty: \t" + this.atrybuty.ToString());
                st.AppendLine("Nosnik: \t\t" + this.Nosnik.Nazwa);
                st.AppendLine("Katalog: \t" + this.KataloG.Nazwa);
                st.AppendLine("Podfoldery: \t" + this.LiczbaPodfolderow.ToString("N0"));
                st.AppendLine("Pliki: \t\t" + this.LiczbaPlikow.ToString("N0"));
                st.AppendLine("Rozmiar: \t" + this.Rozmiar.ToProperUnit());
                return st.ToString();
            }
        }

        public List<Plik> Pliki
        {
            get
            {
                List<Plik> pliki = new List<Plik>();
                foreach (ObiektDyskowy f in obiektyDyskowe)
                {
                    if (f is Plik)
                    {
                        Plik pl = (Plik)f;
                        pliki.Add(pl);
                    }
                }
                return pliki;
            }
        }

        public List<Folder> Podflodery
        {
            get
            {
                List<Folder> folders = new List<Folder>();
                foreach (ObiektDyskowy f in obiektyDyskowe)
                {
                    if (f is Folder)
                    {
                        Folder fr = (Folder)f;
                        folders.Add(fr);
                    }
                }
                return folders;
            }
        }


        /// <summary>
        /// Podaje rozmiar wszystkich plików znajdujących się w Folderze
        /// </summary>
        public override long Rozmiar
        {
            get
            {
                return rozmiarRek(this);
            }

        }

        public override string Sciezka
        {
            get
            {
               return GetSciezka(this);
            }
        }

        public override string SciezkaKatalogu
        {
            get
            {
                string sciez = Sciezka.Substring(3);
                return this.KataloG.Nazwa + Path.DirectorySeparatorChar + Path.Combine(Nosnik.Nazwa, sciez); 
            }

        }

        public override string Typ
        {
            get { return "Folder plików"; }
        }

		#endregion Properties 

		#region Methods (5) 

		// Public Methods (4) 

        public Nosnik GetNosnik(Folder fold)
        {
            if (fold is Cataloger.StrukturaDanych.FolderRoot)
            {
                Cataloger.StrukturaDanych.FolderRoot rt = (Cataloger.StrukturaDanych.FolderRoot)fold;
                return rt.Nosnik1;
            }
            else
            {
                return GetNosnik(fold.Rodzic);
            }
        }

         public override string ToString()
         {
             return Sciezka;
         }

        public override void Uruchom()
         {
             if (this.Nosnik.CzyPodlaczony())
             {
                 if (this.CzyIstniejeSciezka)
                 {
                     Process.Start(SciezkaRzeczyiwsta);
                    
                 }
              
             }
           
        }

        public override void UruchomFolder()
        {
            if (this.Nosnik.CzyPodlaczony())
            {
                if (this.Rodzic.CzyIstniejeSciezka)
                {
                    Process.Start(Path.GetDirectoryName(SciezkaRzeczyiwsta));
                
                }
             

            }
          
        }
		// Private Methods (1) 

        /// <summary>
        /// Metoda pomocnicza dla właściwości Rozmiar.
        /// Zllicza rekurencyjnie rozmiar plików w danym folderze
        /// </summary>
        /// <param name="dir"></param>
        /// <returns></returns>
        private static long rozmiarRek(Folder dir)
        {
            long rozm = 0;
            foreach (Plik fi in dir.Pliki)
            {
                try
                {
                    rozm += fi.Rozmiar;
                }
                catch { }
            }
            foreach (Folder di in dir.Podflodery)
            {
                try
                {
                    rozm += rozmiarRek(di);
                }
                catch { }
            }
            return rozm;
        }

		#endregion Methods 
    
        #region IFoldery Members

        public List<Folder> Foldery
        {
            get
            {
                List<Folder> fold = new List<Folder>();
                fold.AddRange(Podflodery);
                fold.Add(this);
                return fold; 
            }
        }

        #endregion
    }
}
